<template>
  <div class="menuPage">
    <page-template>
      <div slot="title">
        菜单管理
      </div>
      <div slot="headerRight">
        <el-button>创建菜单</el-button>
        <el-button>编辑菜单</el-button>
      </div>
      <div
        slot="content"
        class="content"
      >
        <div class="treeBox">
          <el-tree
            v-loading="pending.getTree"
            :data="menuData"
            :props="defaultProps"
            @node-click="handleNodeClick"
          >
            <div
              slot-scope="{node, data}"
              class="treeItemBox"
              @mouseover="data.showBtn = true"
              @mouseout="data.showBtn = false"
            >
              <div class="treeItemBox-label">
                {{ node.label }}
              </div>
              <div class="treeItemBox-id">
              </div>
              <div
                v-show="data.showBtn"
                class="treeItemBox-btnBox"
              >
                <el-tooltip
                  class="item"
                  effect="dark"
                  content="新增"
                  :open-delay="1000"
                  placement="top"
                >
                  <el-button
                    type="text"
                    icon="el-icon-plus"
                    @click="addMenuFN(data.id)"
                  ></el-button>
                </el-tooltip>
                <el-tooltip
                  class="item"
                  effect="dark"
                  content="查看"
                  :open-delay="1000"
                  placement="top"
                >
                  <el-button
                    type="text"
                    icon="el-icon-view"
                    @click="getMenuDetail('view',data.id)"
                  ></el-button>
                </el-tooltip>
                <el-tooltip
                  class="item"
                  effect="dark"
                  content="编辑"
                  :open-delay="1000"
                  placement="top"
                >
                  <el-button
                    type="text"
                    icon="el-icon-edit"
                    @click="getMenuDetail('edit',data.id)"
                  ></el-button>
                </el-tooltip>
                <el-tooltip
                  class="item"
                  effect="dark"
                  content="删除"
                  :open-delay="1000"
                  placement="top"
                >
                  <el-popconfirm
                    title="确定删除吗?"
                    @onConfirm="deleteMenu(data.id)"
                  >
                    <el-button
                      slot="reference"
                      type="text"
                      style="color:#F56C6C;margin-left:10px;"
                      icon="el-icon-delete"
                    ></el-button>
                  </el-popconfirm>
                </el-tooltip>
              </div>
            </div>
          </el-tree>
          <div style="margin-top:10px;">
            <el-button
              type="primary"
              @click="addMenuFN(-1)"
            >
              添加一级菜单
            </el-button>
          </div>
        </div>
        <div class="menuForm">
          <el-form
            ref="form"
            v-loading="pending.formLoading"
            :model="form"
            :disabled="formDisable"
            label-width="100px"
            :rules="rules"
          >
            <el-form-item
              label="标题"
              prop="name"
            >
              <el-input
                v-model="form.name"
                placeholder="中文标题"
              ></el-input>
            </el-form-item>
            <el-form-item
              v-model="form.type"
              label="类型"
            >
              <el-radio-group
                v-model="form.type"
              >
                <el-radio :label="1">
                  菜单
                </el-radio>
                <el-radio :label="2">
                  按钮
                </el-radio>
              </el-radio-group>
            </el-form-item>
            <el-form-item
              label="排序"
              prop="orderNum"
            >
              <el-input v-model="form.orderNum"></el-input>
            </el-form-item>
            <el-form-item
              v-show="form.type === 2"
              label="权限标识"
            >
              <el-input v-model="form.resource"></el-input>
            </el-form-item>
            <el-form-item
              v-show="form.type === 1"
              label="图标"
            >
              <menu-icon-selecter v-model="form.icon"></menu-icon-selecter>
            </el-form-item>
            <el-form-item
              v-show="form.type === 1"
              label="前端组件"
            >
              <el-input v-model="form.component"></el-input>
            </el-form-item>
            <el-form-item
              v-show="form.type === 1"
              label="菜单路径"
            >
              <el-input v-model="form.href"></el-input>
            </el-form-item>
            <el-form-item
              v-show="form.type === 1"
              label="路由缓存"
            >
              <el-switch
                v-model="form.keepalive"
                :active-value="1"
                :inactive-value="0"
              ></el-switch>
            </el-form-item>
            <el-form-item>
              <el-button
                type="primary"
                @click="saveForm"
              >
                保存
              </el-button>
              <el-button @click="resetForm">
                取消
              </el-button>
            </el-form-item>
          </el-form>
        </div>
      </div>
    </page-template>
  </div>
</template>

<script lang="ts">
import { Component, Vue } from 'vue-property-decorator'
import PageTemplate from '@/components/PageTemplate/index.vue'
import CrudTemplate from '@/components/CrudTemplate/index.vue'
import { isInt } from '@/utils/validate'
import MenuIconSelecter from '@/components/MenuIconSelecter/index.vue'
import { getMenuTree, addMenu, getMenuDetail, updateMenu, deleteMenu } from '@/api/user'
interface MenuForm {
  type?: number
  keepalive?: number
  parentId?: number
  name?: string
  href?: string
  component?: string
  icon?: string
  resource?: string
  orderNum?: string
  description?: string
}
const requireBlur = (message: string) => [{ required: true, trigger: 'blur', message }]
const initForm:MenuForm = {
  type: 1,
  keepalive: 1,
  parentId: -1,
  name: '',
  href: '',
  component: '',
  icon: '',
  resource: '',
  orderNum: '',
  description: ''
}
@Component({
  components: {
    PageTemplate,
    CrudTemplate,
    MenuIconSelecter
  },
  name: 'menuPage'
})
export default class Page extends Vue {
  // data
  form:MenuForm = {}
  pending = {
    getTree: false,
    formLoading: false
  };

  formBtnStatus = 'edit'
  defaultProps = {
    children: 'children',
    label: 'label'
  };

  formDisable = true
  menuData = []

  rules = {
    name: requireBlur('请输入名称'),
    orderNum: [
      {
        required: true,
        trigger: 'blur',
        validator: (rule: any, value: any, callback: any) => {
          isInt(value)
            ? callback()
            : callback(new Error('请输入整数'))
        }
      }
    ]
  };

  // 生命周期
  created() {
    this.initForm()
    this.getData()
    // this.recursionFN(this.menuData)
    // console.log(this.menuData)
  }

  // methods
  // 删除 menu
  async deleteMenu(id: number) {
    const res = await deleteMenu(id)
    console.log(res)
    this.$message.success('删除成功')
    this.getData()
  }

  // 添加一级菜单
  addMenuFN(parentId: number) {
    this.formBtnStatus = 'add'
    this.formDisable = false
    this.initForm()
    console.log(parentId)
    this.form.parentId = parentId
  }

  // 重置form
  resetForm() {
    (this.$refs.form as any).resetFields()
    this.initForm()
    this.formDisable = true
  }

  // 初始化form
  initForm() {
    this.form = { ...initForm }
  }

  // 根据 id 获取 menu 详情
  async getMenuDetail(type: string, id: number) {
    if (type === 'edit') {
      this.formDisable = false
      this.formBtnStatus = 'edit'
    } else {
      this.formDisable = true
    }
    this.pending.formLoading = true
    try {
      const res = await getMenuDetail(id)
      const data: MenuForm = res.data
      console.log(data)
      this.form = data
    } finally {
      this.pending.formLoading = false
    }
  }

  // 获取树形菜单
  async getData() {
    try {
      this.pending.getTree = true
      const res = await getMenuTree()
      console.log(res)
      if (res.data && res.data.length > 0) {
        this.menuData = res.data
        this.recursionFN(this.menuData)
      } else {
        this.menuData = []
      }
    } finally {
      this.pending.getTree = false
    }
  }

  // 保存数据
  saveForm() {
    (this.$refs.form as any).validate(async(valid: boolean) => {
      if (valid) {
        console.log(this.form)
        this.pending.formLoading = true
        try {
          const isEdit = this.formBtnStatus === 'edit'
          const apiFN = isEdit ? updateMenu : addMenu
          const res = await apiFN(this.form)
          this.$message.success(!isEdit ? '新增成功' : '编辑成功')
          this.resetForm()
          this.getData()
          console.log(res)
        } finally {
          this.pending.formLoading = false
        }
      }
    })
  }

  // 递归函数 循环每一个children 给每个item 添加一个 showbtn 字段
  recursionFN(dataItem: any) {
    dataItem.forEach((item: any) => {
      this.$set(item, 'showBtn', false)
      if (item.children && item.children.length > 0) {
        this.recursionFN(item.children)
      }
    })
  }

  handleNodeClick(data: any) {
    console.log(data)
  }
}
</script>

<style lang="scss" scoped>
.menuPage{
  height: 100%;
  .content{
    height: calc(100% - 40px);
    display: flex;
    .menuForm{
      width: 60%;
      padding: 20px;
      background: white;
      box-shadow: 0 0 10px 10px #e4e7ed;
      height: 414px;
      position: sticky;
      top: 20px;
    }
    .treeBox{
      width: 30%;
      margin-right: 40px;
      font-size: 14px;
      .treeItemBox{
        display: flex;
        width: 100%;
        align-content: center;
        justify-content: center;
        line-height: 26px;
        @at-root &-label{
          width: 80px;
        }
        @at-root &-id{
          flex: 1;
        }
        @at-root &-btnBox{
          height: 26px;
          margin-right: 10px;
        }
      }
    }
  }
}
</style>
